// Copyright (c) Symbian Ltd 2008. All rights reserved.
#ifndef RPSGAMESCREENS_
#define RPSGAMESCREENS_

#include "rpsMenuOptions.h"
#include "rpsPlayTimer.h"
#include "roshambo.h"

const TInt KMaxRpsTextElement = 30;
const TInt KRPSScreensHAlignment = 15;

extern TInt gScreenWidth;
extern TInt gScreenHeight;

class CRpsGameEngine;
class CBluetoothManager;
class CGameScreen;
class CWsBitmap;
		
class TGameData
	{
public:
	/**
	 * Any error that could occur during the game
	 */
	TInt iRpsError;
	};

/*
============================================================================
The screens manager. Manages the RPS's screen to display to the player
============================================================================
*/	
class CGameScreenManager : public CBase
	{
public:
	enum TGameState
		{
		ESplashScreen,		//Splash screen, displayed as game starts
		EMainScreen,	 	//Player select one/two players or view the about screen
		EPausedScreen,	 	//When the app loses the focus the pause screen is displayed
		EPlayScreen,	 	//Display the Roshambo game
		EWaitOpponentScreen,//Screen presented to th player for waiting the opponent move
		EResultScreen,	 	//Display the result
		EControlScreen,	 	//For choosing either master or slave mode
		ENotifierScreen,	//Displays a notifier
		EConnectingScreen,  //Screen presented to the Master during connection to the Slave
		EStartScreen,	 	//Screen presented to the Master with the option to kick off the game
		EWaitStartScreen,	//Screen presented to the Slave with a msg to wait for the Master to kick off the game
		EWaitConnScreen, 	//Screen presented to the Slave with a waiting connection msg
		EErrorScreen,	 	//Display any errors to the player	
		EAboutScreen,	 	//About screen
		EGameScreensTotal	//Marks the end of the screen array
		};
	enum TPlayMode
		{
		ESinglePlayer,
		ETwoPlayerShortlink,
		};
public:
	/**
	* NewL.
	* Two-phased constructor.
	* Create a CGameScreenManager object.
	* @aparam aObs a reference to the RPS's engine
	*/
	static CGameScreenManager* NewL(CRpsGameEngine& aEngine);
	
	/**
	* Destructor
	*/
	~CGameScreenManager();
public:
	/**
	* Set the game screen to display
	* @aparam aNewGameState One of the game states
	*/
	void SetGameState(TGameState aNewGameState);	
public:
	/**
	* Set the play mode one or two players
	* @aparam aPlayMode One of the play modes
	*/
	inline void SetPlayMode(TPlayMode aPlayMode) {iPlayMode = aPlayMode;};

	/**
	* Query the RPS game's state
	* @return One of the games states
	*/
	inline TGameState GameState() const {return (iGameState);};

	/**
	* Query the RPS's play mode
	* @return One of the game's play mode (one/two players)
	*/
	inline TPlayMode PlayMode() const {return (iPlayMode);};

	/**
	* @return the pointer to the current game screen been displayed
	*/
	inline CGameScreen* GameScreen() {return (iGameScreens[iGameState]);};

	/**
	* @return a TRoshambo reference
	*/
	inline TRoshambo& Roshambo() {return (iRoshambo);};

	/**
	* @return The reference to the RPS's engine
	*/
	inline CRpsGameEngine& GameEngine() {return iEngine;};
	
	/**
	* @return The reference to the Bluetooth Manager
	*/
	inline CBluetoothManager& BluetoothManager() {return (*iBTManager);};
	
	/**
	* @return The current game data
	*/
	inline TGameData& GameData() {return iGameData;};
	
private:
	/**
	* ConstructL
	* 2nd phase constructor.
	*/
	void ConstructL();
	
	/**
	* CRpsGameEngine 
	* C++ default constructor.
	* @aparam The reference to the RPS's engine
	*/
	CGameScreenManager(CRpsGameEngine& aEngine);
private:
	/**
	* Current state of the game
	*/
	TGameState iGameState;

	/**
	* Current play mode
	*/
	TPlayMode iPlayMode;

	/**
	* Reference to the RPS's engine
	*/
	CRpsGameEngine& iEngine;

	/**
	* Array of CGameScreen pointers.
	*/
	CGameScreen* iGameScreens[EGameScreensTotal];
	
	/**
	* The Roshamo algorithm
	*/
	TRoshambo iRoshambo;
	
	/**
	* The data for the ongoing game
	*/
	TGameData iGameData;
	
	/**
	* For Bluetooth multiplayer games
	*/
	CBluetoothManager* iBTManager;
	};
	
/*
============================================================================
This is displayed as a line of text on the screen
============================================================================
*/	
class TGameScreenItem
	{
public:
	TGameScreenItem(RPS::TMenuOption aOption, const TDesC& aText);	
	TDblQueLink iDlink; // Double-linked list link	
	RPS::TMenuOption iOption;
	TBool iHighlighted; // Indicates whether item is highlighted
	TInt iX; // X position on screen
	TInt iY; // Y position on screen
	TBufC<KMaxRpsTextElement> iText;
	};
	

	/*
============================================================================
The screen interface class - abstract C class
============================================================================
*/	
class CGameScreen : public CBase
		{
	public:
		// Draws the screen
		virtual void DrawGameScreen() =0; 
		// Handles user input and updates game state
		virtual void ProcessInput(TUint& /*aKeyState*/) {}; 
		// Called prior to each screen activation (when switching to it from another state)
		virtual void PreActivate() {}; 
		//Called prior to deactivation (when switching to another game state)
		virtual void DeActivate() {}; 
		virtual ~CGameScreen();
	protected:
		CGameScreen(CGameScreenManager& iGameScreenMgr);
	protected:
		CGameScreenManager& iGameScreenMgr;
		};	
	
/*
============================================================================
A generic menu screen
============================================================================
*/	
class CMenuScreen : public CGameScreen
	{
public:
	virtual ~CMenuScreen();
public: // From CGameScreen
	virtual void DrawGameScreen();
	virtual void ProcessInput(TUint& aKeyState);
protected:	
	CMenuScreen(CGameScreenManager& iGameScreenMgr);
	virtual void DoProcessInput(RPS::TMenuOption aSelected) =0;
protected:
	TDblQue<TGameScreenItem> iItems; // Linked list
	TDblQueIter<TGameScreenItem> iIterator;
	};
	

/*
============================================================================
The main menu screen
============================================================================
*/	
class CMainScreen : public CMenuScreen
	{
public:
	/**
	* NewL.
	* Two-phased constructor.
	* Create a CMainScreen object.
	* @aparam aObs a reference to the Screen Manager
	*/
	static CGameScreen* NewL(CGameScreenManager& aScreenMgr);
protected:	
	virtual void DoProcessInput(RPS::TMenuOption aSelected);
private:
	void ConstructL();
	CMainScreen(CGameScreenManager& aScreenMgr);
	};
	

/*
============================================================================
Play menu screen
============================================================================
*/	
class CPlayScreen : public CMenuScreen
	{
public:
	/**
	* NewL.
	* Two-phased constructor.
	* Create a CGameScreen object.
	* @aparam aObs a reference to the Screen Manager
	*/
	static CGameScreen* NewL(CGameScreenManager& aScreenMgr);
	~CPlayScreen();
	void PlayTimeout();
protected:	
	virtual void DoProcessInput(RPS::TMenuOption aSelected);
	virtual void PreActivate();
	virtual void DeActivate();
private:
	void ConstructL();
	CPlayScreen(CGameScreenManager& aScreenMgr);
private:
	CPlayTimer* iPlayTimer;
	};	
	
/*
============================================================================
About screen
============================================================================
*/	
class CAboutScreen : public CMenuScreen
	{
public:
	/**
	* NewL.
	* Two-phased constructor.
	* Create a CGameScreen object.
	* @aparam aObs a reference to the Screen Manager
	*/
	static CGameScreen* NewL(CGameScreenManager& aScreenMgr);
protected:	// From CMenuScreen
	virtual void DrawGameScreen();
	virtual void DoProcessInput(RPS::TMenuOption aSelected);
private:
	void ConstructL();
	CAboutScreen(CGameScreenManager& aScreenMgr);
	};
	
/*
============================================================================
Pause screen
============================================================================
*/	
class CPauseScreen : public CGameScreen
	{
public:
	/**
	* NewL.
	* Two-phased constructor.
	* Create a CPauseScreen object.
	* @aparam aObs a reference to the Screen Manager
	*/
	static CGameScreen* NewL(CGameScreenManager& aScreenMgr);
	~CPauseScreen();
public: // From CGameScreen
	virtual void DrawGameScreen();
	virtual void ProcessInput(TUint& aKeyState);
	virtual void DeActivate(); 
private:
	void ConstructL();
	CPauseScreen(CGameScreenManager& aScreenMgr);
private:
	CWsBitmap* iBmp;
	TPoint iPos;
	};
/*	
============================================================================
Splash screen
============================================================================
*/	
class CSplashScreen : public CGameScreen
	{
public:
	/**
	* NewL.
	* Two-phased constructor.
	* Create a CPauseScreen object.
	* @aparam aObs a reference to the Screen Manager
	*/
	static CGameScreen* NewL(CGameScreenManager& aScreenMgr);
	~CSplashScreen();
public: // From CGameScreen
	virtual void DrawGameScreen(); 
private:
	void ConstructL();
	CSplashScreen(CGameScreenManager& aScreenMgr);
private:
	TInt iSplashCounter;
	CWsBitmap* iBmp;
	TPoint iPos;
	};	
	
/*
============================================================================
Result screen
============================================================================
*/	
class CResultScreen : public CGameScreen
	{
public:
	/**
	* NewL.
	* Two-phased constructor.
	* Create a CResultScreen object.
	* @aparam aObs a reference to the Screen Manager
	*/
	static CResultScreen* NewL(CGameScreenManager& aScreenMgr);
public: // From CGameScreen
	virtual void DrawGameScreen();
	virtual void ProcessInput(TUint& aKeyState);
private:
	void ConstructL();
	CResultScreen(CGameScreenManager& aScreenMgr);
	TInt attacker;
	};		


/*
============================================================================
Control menu screen. User chooses to be either a Master (the player controls the game) or 
a Slave (the player waits for other player connection)	
============================================================================
*/	
class CControlScreen : public CMenuScreen
	{
public:
	/**
	* NewL.
	* Two-phased constructor.
	* Create a CControlScreen object.
	* @aparam aObs a reference to the Screen Manager
	*/
	static CGameScreen* NewL(CGameScreenManager& aScreenMgr);
protected:	
	virtual void DoProcessInput(RPS::TMenuOption aSelected);
private:
	void ConstructL();
	CControlScreen(CGameScreenManager& aScreenMgr);
	};

/*
============================================================================
Start the game (Master)
============================================================================
*/	
class CStartScreen : public CMenuScreen
	{
public:
	/**
	* NewL.
	* Two-phased constructor.
	* Create a CGameScreen object.
	* @aparam aObs a reference to the Screen Manager
	*/
	static CGameScreen* NewL(CGameScreenManager& aScreenMgr);
protected:	
	virtual void DoProcessInput(RPS::TMenuOption aSelected);
private:
	void ConstructL();
	CStartScreen(CGameScreenManager& aScreenMgr);
	};

/*
============================================================================
Waiting to start the game (Slave mode)
============================================================================
*/	
class CWaitStartScreen : public CGameScreen
	{
public:
	/**
	* NewL.
	* Two-phased constructor.
	* Create a CWaitStartScreen object.
	* @aparam aObs a reference to the Screen Manager
	*/
	static CWaitStartScreen* NewL(CGameScreenManager& aScreenMgr);
public: // From CGameScreen
	virtual void DrawGameScreen();
private:
	void ConstructL();
	CWaitStartScreen(CGameScreenManager& aScreenMgr);
	};		

/*
============================================================================
Waiting for a connection (Slave mode)
============================================================================
*/	
class CWaitConnScreen : public CGameScreen
	{
public:
	/**
	* NewL.
	* Two-phased constructor.
	* Create a CWaitConnScreen object.
	* @aparam aObs a reference to the Screen Manager
	*/
	static CWaitConnScreen* NewL(CGameScreenManager& aScreenMgr);
public: // From CGameScreen
	virtual void DrawGameScreen();
private:
	void ConstructL();
	CWaitConnScreen(CGameScreenManager& aScreenMgr);
	};		

/*
============================================================================
Display a error message to the player
============================================================================
*/	
class CErrorScreen : public CGameScreen
	{
public:
	/**
	* NewL.
	* Two-phased constructor.
	* Create a CErrorScreen object.
	* @aparam aObs a reference to the Screen Manager
	*/
	static CErrorScreen* NewL(CGameScreenManager& aScreenMgr);
public: // From CGameScreen
	virtual void DrawGameScreen();
	virtual void ProcessInput(TUint& aKeyState);
	virtual void DeActivate();
private:
	void ConstructL();
	CErrorScreen(CGameScreenManager& aScreenMgr);
	};		

/*
============================================================================
Display connecting message to the player (Master mode)
============================================================================
*/	
class CConnectingScreen : public CGameScreen
	{
public:
	/**
	* NewL.
	* Two-phased constructor.
	* Create a CConnectingScreen object.
	* @aparam aObs a reference to the Screen Manager
	*/
	static CConnectingScreen* NewL(CGameScreenManager& aScreenMgr);
public: // From CGameScreen
	virtual void DrawGameScreen();
	virtual void ProcessInput(TUint& aKeyState);
private:
	void ConstructL();
	CConnectingScreen(CGameScreenManager& aScreenMgr);
	};		
	
/*
============================================================================
Waiting for the opponent move
============================================================================
*/	
class CWaitOpponentScreen : public CGameScreen
	{
public:
	/**
	* NewL.
	* Two-phased constructor.
	* Create a CWaitConnScreen object.
	* @aparam aObs a reference to the Screen Manager
	*/
	static CWaitOpponentScreen* NewL(CGameScreenManager& aScreenMgr);
public: // From CGameScreen
	virtual void DrawGameScreen();
private:
	void ConstructL();
	CWaitOpponentScreen(CGameScreenManager& aScreenMgr);
	};	
	
	
class CNotifierScreen : public CGameScreen
	{
public:
	static CNotifierScreen* NewL(CGameScreenManager& aGameScreenMgr);
	~CNotifierScreen();
public: // From CGameScreen
	virtual void DrawGameScreen();
private:
	CNotifierScreen(CGameScreenManager& aGameScreenMgr);	
	};

#endif /*RPSGAMESCREENS_*/
